﻿using System;
using System.Collections.Generic;
using UnityEngine;

namespace Sizebox.CharacterEditor
{
	// Token: 0x0200025E RID: 606
	public class EditBone : MonoBehaviour
	{
		// Token: 0x1700018A RID: 394
		// (get) Token: 0x06000D44 RID: 3396 RVA: 0x00069446 File Offset: 0x00067646
		// (set) Token: 0x06000D45 RID: 3397 RVA: 0x0006944E File Offset: 0x0006764E
		public bool Enabled { get; private set; }

		// Token: 0x1700018B RID: 395
		// (get) Token: 0x06000D46 RID: 3398 RVA: 0x00069457 File Offset: 0x00067657
		// (set) Token: 0x06000D47 RID: 3399 RVA: 0x0006945F File Offset: 0x0006765F
		public string Key { get; private set; }

		// Token: 0x1700018C RID: 396
		// (get) Token: 0x06000D48 RID: 3400 RVA: 0x00069468 File Offset: 0x00067668
		public Transform EditBone0
		{
			get
			{
				return this.editBone0;
			}
		}

		// Token: 0x1700018D RID: 397
		// (get) Token: 0x06000D49 RID: 3401 RVA: 0x00069470 File Offset: 0x00067670
		public Transform EditBone1
		{
			get
			{
				return this.editBone1;
			}
		}

		// Token: 0x1700018E RID: 398
		// (get) Token: 0x06000D4A RID: 3402 RVA: 0x00069478 File Offset: 0x00067678
		// (set) Token: 0x06000D4B RID: 3403 RVA: 0x00069480 File Offset: 0x00067680
		public Transform RealTransform { get; private set; }

		// Token: 0x1700018F RID: 399
		// (get) Token: 0x06000D4C RID: 3404 RVA: 0x00069489 File Offset: 0x00067689
		// (set) Token: 0x06000D4D RID: 3405 RVA: 0x00069491 File Offset: 0x00067691
		public EditBone ParentBone { get; private set; }

		// Token: 0x17000190 RID: 400
		// (get) Token: 0x06000D4E RID: 3406 RVA: 0x0006949A File Offset: 0x0006769A
		// (set) Token: 0x06000D4F RID: 3407 RVA: 0x000694A2 File Offset: 0x000676A2
		public EditBone SiblingBone { get; private set; }

		// Token: 0x06000D50 RID: 3408 RVA: 0x000694AC File Offset: 0x000676AC
		public void Initialize(string key, SkeletonEdit editor, Transform realBone, EditBone parentBone = null)
		{
			this.Key = key;
			this.Editor = editor;
			this.RealTransform = realBone;
			this.cachedLocalPos = this.RealTransform.localPosition;
			base.name = "   EDIT BONE 00: " + realBone.name;
			this.SetDataScale("body", realBone.localScale);
			this.editBone0.parent = realBone.parent;
			this.editBone0.localPosition = Vector3.zero;
			this.editBone0.localRotation = Quaternion.identity;
			this.editBone0.localScale = Vector3.one;
			if (parentBone)
			{
				this.ParentBone = parentBone;
				parentBone.RegisterChild(this);
			}
			this.Enable();
		}

		// Token: 0x06000D51 RID: 3409 RVA: 0x00069569 File Offset: 0x00067769
		public void SetParent(EditBone parent)
		{
			this.ParentBone = parent;
		}

		// Token: 0x06000D52 RID: 3410 RVA: 0x00069572 File Offset: 0x00067772
		public void RegisterChild(EditBone child)
		{
			if (!this.childrenBones.Contains(child))
			{
				this.childrenBones.Add(child);
			}
			child.SetParent(this);
		}

		// Token: 0x06000D53 RID: 3411 RVA: 0x00069598 File Offset: 0x00067798
		public void UnregisterChild(EditBone child)
		{
			if (this.childrenBones.Contains(child))
			{
				this.childrenBones.Remove(child);
			}
		}

		// Token: 0x06000D54 RID: 3412 RVA: 0x000695B8 File Offset: 0x000677B8
		public void SetSibling(EditBone sibling)
		{
			this.SiblingBone = sibling;
		}

		// Token: 0x06000D55 RID: 3413 RVA: 0x000695C4 File Offset: 0x000677C4
		public Vector3 Move(string id, Vector3 movement, SkeletonEditMovementOptions options, bool scaleInput = true)
		{
			this.EnsureId(id);
			BoneTransformData value = this.Data[id];
			Vector3 movement2 = movement;
			movement2.x = -movement2.x;
			movement *= options.speed;
			if (scaleInput)
			{
				movement = Vector3.Scale(movement, this.editBone1.lossyScale);
			}
			movement = this.Editor.transform.rotation * movement;
			Vector3 localPosition = this.editBone1.localPosition;
			this.editBone1.position += movement;
			Vector3 localPosition2 = this.editBone1.localPosition;
			value.position += localPosition2 - localPosition;
			this.Data[id] = value;
			if (this.SiblingBone && options.effectPairs)
			{
				options.effectPairs = false;
				this.SiblingBone.Move(id, movement2, options, true);
			}
			return movement;
		}

		// Token: 0x06000D56 RID: 3414 RVA: 0x000696C4 File Offset: 0x000678C4
		public void Rotate(string id, Quaternion rotation, SkeletonEditRotationOptions options)
		{
			this.EnsureId(id);
			BoneTransformData value = this.Data[id];
			value.rotation *= rotation;
			this.Data[id] = value;
			if (this.SiblingBone && options.effectPairs)
			{
				options.effectPairs = false;
				this.SiblingBone.Rotate(id, this.HandleRotationMirroring(rotation, options), options);
			}
			this.UpdateRotation();
		}

		// Token: 0x06000D57 RID: 3415 RVA: 0x00069748 File Offset: 0x00067948
		public void Scale(string id, Vector3 scaling, SkeletonEditScalingOptions options)
		{
			if (this.SiblingBone && options.effectPairs)
			{
				options.effectPairs = false;
				this.SiblingBone.Scale(id, scaling, options);
			}
			this.EnsureId(id);
			BoneTransformData value = this.Data[id];
			Vector3 scale = value.scale;
			value.scale = Vector3.Scale(value.scale, scaling);
			value.scale = this.ClampVector(value.scale, 1E-05f, 10000f);
			Vector3 scaling2;
			scaling2.x = value.scale.x / scale.x;
			scaling2.y = value.scale.y / scale.y;
			scaling2.z = value.scale.z / scale.z;
			if (options.scaleWithoutChildren)
			{
				foreach (EditBone editBone in this.childrenBones)
				{
					editBone.ScaleAgainst(id, scaling2);
				}
			}
			this.Data[id] = value;
			this.UpdateScale(true);
		}

		// Token: 0x06000D58 RID: 3416 RVA: 0x00069898 File Offset: 0x00067A98
		public void ScaleAgainst(string id, Vector3 scaling)
		{
			this.EnsureId(id);
			BoneTransformData value = this.Data[id];
			scaling = this.InvertScaling(scaling);
			value.scale = Vector3.Scale(value.scale, scaling);
			this.Data[id] = value;
			this.UpdateScale(true);
		}

		// Token: 0x06000D59 RID: 3417 RVA: 0x000698EC File Offset: 0x00067AEC
		public void Enable()
		{
			if (this.Enabled || !this.RealTransform)
			{
				return;
			}
			this.Enabled = true;
			this.RealTransform.SetParent(this.editBone1, true);
			this.RealTransform.localPosition = this.cachedLocalPos;
		}

		// Token: 0x06000D5A RID: 3418 RVA: 0x00069940 File Offset: 0x00067B40
		public void Disable()
		{
			if (!this.Enabled || !this.RealTransform)
			{
				return;
			}
			this.cachedLocalPos = this.RealTransform.localPosition;
			this.Enabled = false;
			this.RealTransform.SetParent(this.editBone0.parent, true);
		}

		// Token: 0x06000D5B RID: 3419 RVA: 0x00069998 File Offset: 0x00067B98
		public void ResetAll(string id)
		{
			this.EnsureId(id);
			BoneTransformData value = this.Data[id];
			value.position = Vector3.zero;
			value.rotation = Quaternion.identity;
			value.scale = Vector3.one;
			this.Data[id] = value;
			this.UpdateTransformation();
		}

		// Token: 0x06000D5C RID: 3420 RVA: 0x000699F0 File Offset: 0x00067BF0
		public void ResetPosition(string id, SkeletonEditMovementOptions movementOptions)
		{
			this.EnsureId(id);
			BoneTransformData value = this.Data[id];
			value.position = Vector3.zero;
			this.Data[id] = value;
			if (this.SiblingBone && movementOptions.effectPairs)
			{
				movementOptions.effectPairs = false;
				this.SiblingBone.ResetPosition(id, movementOptions);
			}
			this.UpdatePosition();
		}

		// Token: 0x06000D5D RID: 3421 RVA: 0x00069A64 File Offset: 0x00067C64
		public void ResetRotation(string id, SkeletonEditRotationOptions rotationOptions)
		{
			this.EnsureId(id);
			BoneTransformData value = this.Data[id];
			value.rotation = Quaternion.identity;
			this.Data[id] = value;
			this.editBone1.localPosition = Vector3.zero;
			if (this.SiblingBone && rotationOptions.effectPairs)
			{
				rotationOptions.effectPairs = false;
				this.SiblingBone.ResetRotation(id, rotationOptions);
			}
			this.UpdateRotation();
		}

		// Token: 0x06000D5E RID: 3422 RVA: 0x00069AE8 File Offset: 0x00067CE8
		public void ResetScaling(string id, SkeletonEditScalingOptions scalingOptions)
		{
			this.EnsureId(id);
			BoneTransformData value = this.Data[id];
			Vector3 scale = value.scale;
			value.scale = Vector3.one;
			this.Data[id] = value;
			if (scalingOptions.scaleWithoutChildren)
			{
				Vector3 scaling;
				scaling.x = value.scale.x / scale.x;
				scaling.y = value.scale.y / scale.y;
				scaling.z = value.scale.z / scale.z;
				foreach (EditBone editBone in this.childrenBones)
				{
					editBone.ScaleAgainst(id, scaling);
				}
			}
			if (this.SiblingBone && scalingOptions.effectPairs)
			{
				scalingOptions.effectPairs = false;
				this.SiblingBone.ResetScaling(id, scalingOptions);
			}
			this.UpdateScale(true);
		}

		// Token: 0x06000D5F RID: 3423 RVA: 0x00069C10 File Offset: 0x00067E10
		public void UpdateTransformation()
		{
			this.UpdateScale(true);
			this.UpdateRotation();
			this.UpdatePosition();
		}

		// Token: 0x06000D60 RID: 3424 RVA: 0x00069C28 File Offset: 0x00067E28
		public void UpdateTransformationRecursive()
		{
			this.UpdateScale(false);
			this.UpdateRotation();
			this.UpdatePosition();
			foreach (EditBone editBone in this.childrenBones)
			{
				editBone.UpdateTransformationRecursive();
			}
		}

		// Token: 0x06000D61 RID: 3425 RVA: 0x00069C98 File Offset: 0x00067E98
		private void UpdatePosition()
		{
			this.editBone1.localPosition = this.GetDataPosition();
		}

		// Token: 0x06000D62 RID: 3426 RVA: 0x00069CAB File Offset: 0x00067EAB
		private void UpdateRotation()
		{
			this.editBone1.localRotation = this.GetDataRotation();
			this.UpdateRotationCorrection();
			this.UpdateCorrectionPosition();
		}

		// Token: 0x06000D63 RID: 3427 RVA: 0x00069CCA File Offset: 0x00067ECA
		public void UpdateScale(bool scaleChildren = true)
		{
			this.RealTransform.localScale = Vector3.Scale(this.GetDataScale(), this.InvertScaling(this.editBone0.localScale));
			this.NormalizeChildrenScale(scaleChildren);
		}

		// Token: 0x06000D64 RID: 3428 RVA: 0x00069CFA File Offset: 0x00067EFA
		private void UpdateCorrectionPosition()
		{
			this.editBone0.localPosition = this.normalizationCorrection + this.rotationCorrection;
		}

		// Token: 0x06000D65 RID: 3429 RVA: 0x00069D18 File Offset: 0x00067F18
		private void UpdateNormalizationCorrection(Transform parent)
		{
			this.editBone0.localPosition = Vector3.zero;
			Vector3 localPosition = this.editBone1.localPosition;
			Quaternion localRotation = this.editBone1.localRotation;
			this.editBone1.localPosition = Vector3.zero;
			this.editBone1.localRotation = Quaternion.identity;
			Vector3 vector = parent.InverseTransformPoint(this.RealTransform.position);
			Vector3 a = Vector3.Scale(vector, parent.localScale);
			Vector3 vector2 = a - vector;
			this.editBone1.localPosition = localPosition;
			this.editBone1.localRotation = localRotation;
			this.normalizationCorrection = vector2;
		}

		// Token: 0x06000D66 RID: 3430 RVA: 0x00069DB8 File Offset: 0x00067FB8
		private void UpdateRotationCorrection()
		{
			Vector3 localPosition = this.editBone0.localPosition;
			this.editBone0.localPosition = Vector3.zero;
			Quaternion localRotation = this.editBone1.localRotation;
			this.editBone1.localRotation = Quaternion.identity;
			Vector3 position = this.RealTransform.position;
			this.editBone1.localRotation = localRotation;
			Vector3 position2 = this.RealTransform.position;
			Vector3 b = position - position2;
			this.editBone0.position += b;
			this.rotationCorrection = this.editBone0.localPosition;
			this.editBone0.localPosition = localPosition;
		}

		// Token: 0x06000D67 RID: 3431 RVA: 0x00069E60 File Offset: 0x00068060
		private void NormalizeChildrenScale(bool updateScale = true)
		{
			foreach (EditBone editBone in this.childrenBones)
			{
				editBone.NormalizeLocalScale(this.RealTransform, updateScale);
			}
		}

		// Token: 0x06000D68 RID: 3432 RVA: 0x00069EC4 File Offset: 0x000680C4
		public void NormalizeLocalScale(Transform parentTransform, bool updateScale = true)
		{
			this.editBone0.localScale = this.InvertScaling(parentTransform.localScale);
			this.UpdateNormalizationCorrection(parentTransform);
			this.UpdateCorrectionPosition();
			if (updateScale)
			{
				this.UpdateScale(true);
			}
		}

		// Token: 0x06000D69 RID: 3433 RVA: 0x00069EF8 File Offset: 0x000680F8
		private void EnsureId(string id)
		{
			if (this.Data.ContainsKey(id))
			{
				return;
			}
			BoneTransformData @default = BoneTransformData.Default;
			this.Data.Add(id, @default);
		}

		// Token: 0x06000D6A RID: 3434 RVA: 0x00069F2A File Offset: 0x0006812A
		public BoneTransformData GetData(string id)
		{
			this.EnsureId(id);
			return this.Data[id];
		}

		// Token: 0x06000D6B RID: 3435 RVA: 0x00069F3F File Offset: 0x0006813F
		public void SetData(string id, BoneTransformData inData)
		{
			this.EnsureId(id);
			this.Data[id] = inData;
			this.NormalizeChildrenScale(true);
			this.UpdateTransformation();
		}

		// Token: 0x06000D6C RID: 3436 RVA: 0x00069F64 File Offset: 0x00068164
		public void SetDataPosition(string id, Vector3 position)
		{
			this.EnsureId(id);
			BoneTransformData value = this.Data[id];
			value.position = position;
			this.Data[id] = value;
		}

		// Token: 0x06000D6D RID: 3437 RVA: 0x00069F9C File Offset: 0x0006819C
		public void SetDataRotation(string id, Quaternion rotation)
		{
			this.EnsureId(id);
			BoneTransformData value = this.Data[id];
			value.rotation = rotation;
			this.Data[id] = value;
		}

		// Token: 0x06000D6E RID: 3438 RVA: 0x00069FD4 File Offset: 0x000681D4
		public void SetDataScale(string id, Vector3 scale)
		{
			this.EnsureId(id);
			BoneTransformData value = this.Data[id];
			value.scale = scale;
			this.Data[id] = value;
		}

		// Token: 0x06000D6F RID: 3439 RVA: 0x0006A00C File Offset: 0x0006820C
		private Vector3 GetDataPosition()
		{
			Vector3 vector = Vector3.zero;
			foreach (KeyValuePair<string, BoneTransformData> keyValuePair in this.Data)
			{
				vector += keyValuePair.Value.position;
			}
			return vector;
		}

		// Token: 0x06000D70 RID: 3440 RVA: 0x0006A080 File Offset: 0x00068280
		private Quaternion GetDataRotation()
		{
			Quaternion quaternion = Quaternion.identity;
			foreach (KeyValuePair<string, BoneTransformData> keyValuePair in this.Data)
			{
				quaternion *= keyValuePair.Value.rotation;
			}
			return quaternion;
		}

		// Token: 0x06000D71 RID: 3441 RVA: 0x0006A0F4 File Offset: 0x000682F4
		private Vector3 GetDataScale()
		{
			Vector3 one = Vector3.one;
			foreach (KeyValuePair<string, BoneTransformData> keyValuePair in this.Data)
			{
				one.Scale(keyValuePair.Value.scale);
			}
			return one;
		}

		// Token: 0x06000D72 RID: 3442 RVA: 0x0006A168 File Offset: 0x00068368
		private void OnDestroy()
		{
			if (this.ParentBone)
			{
				this.ParentBone.UnregisterChild(this);
				foreach (EditBone editBone in this.childrenBones)
				{
					this.ParentBone.RegisterChild(editBone);
					editBone.SetParent(this.ParentBone);
				}
			}
			this.Editor.BoneMap.Remove(this.Key);
		}

		// Token: 0x06000D73 RID: 3443 RVA: 0x0006A208 File Offset: 0x00068408
		private Quaternion HandleRotationMirroring(Quaternion rotation, SkeletonEditRotationOptions rotationOptions)
		{
			if (!rotationOptions.invertX && !rotationOptions.invertY && !rotationOptions.invertZ)
			{
				return rotation;
			}
			if (rotationOptions.invertX && rotationOptions.invertY && rotationOptions.invertZ)
			{
				return Quaternion.Inverse(rotation);
			}
			if (rotationOptions.invertX)
			{
				rotation.y *= -1f;
				rotation.z *= -1f;
			}
			if (rotationOptions.invertY)
			{
				rotation.x *= -1f;
				rotation.z *= -1f;
			}
			if (rotationOptions.invertZ)
			{
				rotation.x *= -1f;
				rotation.y *= -1f;
			}
			return rotation;
		}

		// Token: 0x06000D74 RID: 3444 RVA: 0x0006A300 File Offset: 0x00068500
		private Vector3 ClampVector(Vector3 vector, float min, float max)
		{
			if (vector.x < min)
			{
				vector.x = min;
			}
			else if (vector.x > max)
			{
				vector.x = max;
			}
			if (vector.y < min)
			{
				vector.y = min;
			}
			else if (vector.y > max)
			{
				vector.y = max;
			}
			if (vector.z < min)
			{
				vector.z = min;
			}
			else if (vector.z > max)
			{
				vector.z = max;
			}
			return vector;
		}

		// Token: 0x06000D75 RID: 3445 RVA: 0x0006A39B File Offset: 0x0006859B
		private Vector3 InvertScaling(Vector3 scaling)
		{
			scaling.x = 1f / scaling.x;
			scaling.y = 1f / scaling.y;
			scaling.z = 1f / scaling.z;
			return scaling;
		}

		// Token: 0x04001245 RID: 4677
		private const float MIN_SCALE = 1E-05f;

		// Token: 0x04001246 RID: 4678
		private const float MAX_SCALE = 10000f;

		// Token: 0x04001247 RID: 4679
		private const string NAME_PREFIX = "   EDIT BONE 00: ";

		// Token: 0x04001248 RID: 4680
		private const string DEFAULT_DATA_ID = "body";

		// Token: 0x0400124A RID: 4682
		private Vector3 cachedLocalPos;

		// Token: 0x0400124B RID: 4683
		private SkeletonEdit Editor;

		// Token: 0x0400124D RID: 4685
		private Dictionary<string, BoneTransformData> Data = new Dictionary<string, BoneTransformData>();

		// Token: 0x0400124E RID: 4686
		private Vector3 rotationCorrection;

		// Token: 0x0400124F RID: 4687
		private Vector3 normalizationCorrection;

		// Token: 0x04001250 RID: 4688
		[SerializeField]
		private Transform editBone0;

		// Token: 0x04001251 RID: 4689
		[SerializeField]
		private Transform editBone1;

		// Token: 0x04001255 RID: 4693
		private List<EditBone> childrenBones = new List<EditBone>();
	}
}
